package achi.community.irla.beans;

import achi.community.irla.database.Crypto;
import achi.community.irla.database.DatabaseImpl;
import achi.community.irla.database.ModelBean;
import achi.community.irla.entities.Users;
import com.icesoft.faces.context.effects.Effect;
import com.icesoft.faces.context.effects.Highlight;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.lang.String;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.application.ViewHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.FacesEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.validator.ValidatorException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * RegControlBean:
 * Validation for register.xhtml
 * Adds the new Customer to DB and ModelBean
 */
@ManagedBean
@RequestScoped
public class RegisterControlBean implements Serializable {

    @EJB
    DatabaseImpl db;
    @ManagedProperty(value = "#{registerBackBean}")
    RegisterBackBean backingBean;
    @ManagedProperty(value = "#{modelBean}")
    ModelBean modelBean;
    private boolean showPopup = false;

    public void setModelBean(ModelBean modelBean) {
        this.modelBean = modelBean;
    }

    public ModelBean getModelBean() {
        return modelBean;
    }

    public RegisterBackBean getBackingBean() {
        return backingBean;
    }

    public void setBackingBean(RegisterBackBean backingBean) {
        this.backingBean = backingBean;
    }

    public void viewCheckName(ValueChangeEvent event) {
        //System.out.println("viewCheckName!");
        String input = event.getNewValue().toString();
        //  System.out.println("viewCheckName!: "+input);
        String id = event.getComponent().getClientId();
        checkName(input, id);
    }

    public void viewCheckPassword(ValueChangeEvent event) {
        String input = event.getNewValue().toString();
        String id = event.getComponent().getClientId();
        checkPassword(input, id);
    }

    public void viewCheckEmail(ValueChangeEvent event) {
        String input = event.getNewValue().toString();
        String id = event.getComponent().getClientId();
        checkEmail(input, id);
    }

    public void checkPassword(String input, String id) {
        if (!checkLength(input, 3, 20)) {
            putMessage(id, "fields.error.password");
        }
    }

    public boolean checkLength(String input, int min, int max) {
        int length = input.length();
        if (length > min && length < max) {
            return true;
        } else {
            return false;
        }
    }

    public boolean checkLetters(String input) {
        int count = 0;
        int length = input.length();
        while (count < length && Character.isLetter(input.charAt(count))) {
            count++;
        }
        if (count < length) {
            //putMessage(id, "fields.error.letters");
            return false;
        } else {
            return true;
        }
    }

    public boolean checkName(String input, String id) {
        if (checkLength(input, 0, 20)) {
            if (!checkLetters(input)) {
                putMessage(id, "fields.error.letters");
                return false;
            }
        } else {
            putMessage(id, "fields.error.required");
            return false;
        }
        return true;
    }

    public void letterDigitBlank(FacesContext context, UIComponent component, Object value) {
        String input = value.toString();

        if (input.length() > 1) {
            for (int i = 0; i < input.length(); i++) {
                if (!Character.isLetterOrDigit(input.charAt(i)) && input.charAt(i) != ' ') {
                    FacesMessage msg = new FacesMessage("only normal chars");
                    throw new ValidatorException(msg);
                }
            }
        } else {
            FacesMessage msg = new FacesMessage("Required field");
            throw new ValidatorException(msg);
        }
    }

    public void onlyLetter() {
        System.out.println("onlyLetters!!");
        /**
        //ValueChangeEvent event) {
        if(event!=null){
        String input = event.getNewValue().toString();
        String id = event.getComponent().getClientId();

        int length = input.length();
        if (length > 1) {
        int count = 0;
        while (count < length && Character.isLetter(input.charAt(count))) {
        count++;
        }
        if (count < length) {
        putMessage(id, "fields.error.letters");
        fieldOk = false;
        } else {
        fieldOk = true;
        }
        /**
        for (int i = 0; i < input.length() && Character.isLetter(input.charAt(i)); i++) {
        if (!Character.isLetter(input.charAt(i))) {
        putMessage(id, "fields.error.letters");
        fieldOk = false;
        }
        else
        fieldOk = true;
        }
         * */
        /**
        } else {
        putMessage(id, "fields.error.required");
        fieldOk = false;
        }
        }
        else
        fieldOk=true;
        //checkFields();
         * */
    }

    public void checkFields() {
        /**
        if(fieldOk){
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent btn = context.getViewRoot().findComponent("btnRegister");
        CommandButton b = (CommandButton)btn;

        CommandButton a;

        UIViewRoot root = context.getViewRoot();
        }
         */
    }

    public void putMessage(String id, String key) {
        ResourceBundle resourceBundle = ResourceBundle.getBundle("MessageBoundle", FacesContext.getCurrentInstance().getViewRoot().getLocale());
        String value = resourceBundle.getString(key);
        FacesMessage msg = new FacesMessage(value);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(id, msg);
    }

    /**
    public void onlyLetter(FacesContext context, UIComponent validate, Object value)
    {
    //FacesMessage msg = new FacesMessage("Required field");
    // context.addMessage(validate.getClientId(context), msg);
    //throw new ValidatorException(msg);

    String input = value.toString();
    if( input.length() > 1)
    {
    for(int i = 0; i < input.length(); i++)
    if (!Character.isLetter(input.charAt(i)))
    {
    FacesMessage msg = new FacesMessage("Field must be letters");
    throw new ValidatorException(msg);
    }
    }
    else
    {
    FacesMessage msg = new FacesMessage("Required field");
    throw new ValidatorException(msg);
    }

    }
     */
    public void notShort(FacesContext context, UIComponent component, Object value) {
        String input = value.toString();
        if (input == null || input.length() < 4) {
            FacesMessage msg = new FacesMessage("Password to short");
            throw new ValidatorException(msg);
        }
    }

    public boolean checkEmail(String input, String id) {
        boolean isOk = false;
        boolean oneDot = false;
        int atCount = 0;
        for (int i = 0; i < input.length(); i++) {
            if (input.charAt(i) == '@') {
                atCount++;
            } else if (input.charAt(i) == '.') {
                oneDot = true;
            }
        }

        if (atCount == 1 && oneDot) {
            isOk = true;
        }

        if (!isOk) {
            putMessage(id, "fields.error.email");

            //FacesMessage msg = new FacesMessage("not valid mail address");
            //throw new ValidatorException(msg);
        }
        return isOk;
    }

    public String getClientId(String id) {
        FacesContext context = FacesContext.getCurrentInstance();
        UIViewRoot root = context.getViewRoot();
        return findComponent(root, id).getClientId();
    }

    /**
     * Finds component with the given id
     */
    private UIComponent findComponent(UIComponent c, String id) {
        if (id.equals(c.getId())) {
            return c;
        }
        Iterator<UIComponent> kids = c.getFacetsAndChildren();
        while (kids.hasNext()) {
            UIComponent found = findComponent(kids.next(), id);
            if (found != null) {
                return found;
            }
        }
        return null;
    }

    public void buttonClicked() {//ActionEvent evt) {
        // System.out.println("buttonClicked!(1)");

        if (checkAllFields()) {
            showPopup = true;
            //return "news";
        }// else {
//            return "register";
        //      }
        /**
        String input = backingBean.getFirstname();
        String id = getClientId("TxtFname");

        if (checkName(input, id)) {
        System.out.println("buttonClicked!!!!!!");
        withConfirmation = true;
        } else {
        System.out.println("denied");
        }

        input = backingBean.getLastname();
        id = getClientId("TxtLname");
        checkName(input, id);
         */
        //    System.out.println("#2");
        //FacesEvent a = new FacesEvent();
        // checkFirstname();
        //UICommandButton a;
        //System.out.println("buttonClicked!!!!!!");
        // String input = backingBean.getName();
        // System.out.println("buttonClicked:" + input);
        /**
        if (fieldOk) {
        return "news";
        } else {
        return "register";
        }*/
        /**
        String fname = backingBean.getFname();
        String lname = backingBean.getLname();
        String mail = backingBean.getMail();
        String password = backingBean.getPassword();
        String street = backingBean.getStreet();
        String city = backingBean.getCity();
        String country = backingBean.getCountry();

        Address adr = new Address(street, city, country);
        Customer cust = new Customer(fname, lname, mail, password, adr);

        db.addCustomer(cust);
        modelBean.setCustomer(cust);

        return "home";
         */
    }

    public boolean checkAllFields() {
        boolean fieldsOk = true;
        String input = backingBean.getFirstname();
        String id = getClientId("TxtFname");
        if (!checkName(input, id)) {
            fieldsOk = false;
        }

        input = backingBean.getLastname();
        id = getClientId("TxtLname");
        if (!checkName(input, id)) {
            fieldsOk = false;
        }

        input = backingBean.getUsername();
        id = getClientId("TxtUname");
        if (!checkName(input, id)) {
            fieldsOk = false;
        }

        input = backingBean.getPassword();
        id = getClientId("TxtPassword");
        if (!checkName(input, id)) {
            fieldsOk = false;
        }

        input = backingBean.getEmail();
        id = getClientId("TxtEmail");
        if (!checkEmail(input, id)) {
            fieldsOk = false;
        }

        return fieldsOk;
    }

    public boolean isWithConfirmation() {
        return showPopup;
    }

    public String popupAccept() {
        String firstname = backingBean.getFirstname();
        String lastname = backingBean.getLastname();
        String email = backingBean.getEmail();
        String username = backingBean.getUsername();
        String password = backingBean.getPassword();
        try {
            password = Crypto.byteArrayToHexString(Crypto.computeHash(password));
        } catch (Exception e) {
            return "error";
        }
        Users user = new Users(firstname, lastname, email, username, password, null);
        user.setEmail(backingBean.getEmail());
        db.addUser(user);
        modelBean.setUser(user);

        return "news";
    }

    public void update() {
        FacesContext context = FacesContext.getCurrentInstance();
        String viewId = context.getViewRoot().getViewId();
        ViewHandler handler = context.getApplication().getViewHandler();
        UIViewRoot root = handler.createView(context, viewId);
        root.setViewId(viewId);
        context.setViewRoot(root);
    }
}
